#include "manano_common.h"

#include "mdtx-online/indicator/indicator_type_ma.h"
#include "mdtx-online/indicator/indicator_type_ma_macd.h"
namespace indi = mdtx::online::indicator;

using macd = unary3<indi::macd<indi::ema>>;
using tmacd = unary3<indi::macd<indi::tma>>;
using wmacd = unary3<indi::macd<indi::wma>>;
using hmacd = unary3<indi::macd<indi::hma>>;
using demacd = unary3<indi::macd<indi::dema>>;
using temacd = unary3<indi::macd<indi::tema>>;
using t3macd = unary3<indi::macd<indi::t3ma>>;
using ewmacd = unary3<indi::macd<indi::ewma>>;
using zlemacd = unary3<indi::macd<indi::zlema>>;

using vwmacd = binary3<indi::wmacd<indi::vwma>>;
using evwmacd = binary3<indi::wmacd<indi::evwma>>;

void bind_indi_ma_macd(py::module &m)
{
    auto mod = m.def_submodule("macd", "Moving average convergence/divergence indicators");
    {
        auto v = py::class_<macd>(mod, "ema")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &macd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &macd::run2, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of EMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<tmacd>(mod, "tma")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &tmacd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &tmacd::run2, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of TEMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<wmacd>(mod, "wma")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &wmacd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &wmacd::run2, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of WMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<hmacd>(mod, "hma")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &hmacd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &hmacd::run2, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of HMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<demacd>(mod, "dema")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &demacd::run, py::arg("x"),
                          R"mydoc(Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &demacd::run2, py::arg("x"),
                          R"mydoc(Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of DEMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<temacd>(mod, "tema")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &temacd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &temacd::run2, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of TEMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<t3macd>(mod, "t3ma")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &t3macd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &t3macd::run2, py::arg("x"),
                          R"mydoc(Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of T3MA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<ewmacd>(mod, "ewma")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &ewmacd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &ewmacd::run2, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of EWMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<zlemacd>(mod, "zlema")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &zlemacd::run, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &zlemacd::run2, py::arg("x"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of ZLEMA
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }

    {
        auto v = py::class_<vwmacd>(m, "vwma")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &vwmacd::run, py::arg("x"), py::arg("w"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                                w (float64) : volume (weight)
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &vwmacd::run2, py::arg("x"), py::arg("w"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                                w (numpy.array) : volume (weighted)
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of VWMA (volume weighted moving average)
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
    {
        auto v = py::class_<evwmacd>(m, "evwma")
                     .def(py::init<int, int, int>(), py::arg("fast_period"), py::arg("slow_period"), py::arg("sig_period"))
                     .def("run", &evwmacd::run, py::arg("x"), py::arg("w"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (float64) : input data
                                w (float64) : volume (weight)
                             Return:
                                MACD (float64)
                                Signal (float64)
                                Histogram (float64))mydoc")
                     .def("run", &evwmacd::run2, py::arg("x"), py::arg("w"),
                          R"mydoc(
                             Run calculation
                             Args:
                                x (numpy.array) : input data
                                w (numpy.array) : volume (weighted)
                             Return:
                                MACD (numpy.array)
                                Signal (numpy.array)
                                Histogram (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    MACD of EVWMA (elastic volume weighted moving average)
                    Args:
                        fast_period (int) : fast MA period
                        slow_period (int) : slow MA period
                        sig_period (int) : signal MA period)mydoc";
    }
}
